package com.android.task5;

import java.util.Iterator;
import java.util.List;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.location.Location;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;

public class LocationBasedPhotoBrowser extends MapActivity {
	
	final int MENU_START = 0;
	final int MENU_CHANGE_MODE = 1;
	final int MENU_GET_PHOTOS = 2;
	private service serviceProxy;
	private ServiceConnection serviceConnection;
	
	double latitude;
	double longitude;
	MapView mapView;
	boolean started = false;
	boolean isGPSActivated = true;
	
	 /** Overlay for drawing the circle representing the GPS position */
	CustomOverlay overlay;
	
	private Menu appMenu;
    /** Called when the activity is first created. */
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mapView = (MapView) findViewById(R.id.mapview);
        mapView.setBuiltInZoomControls(true);

        initializeService();
        
    }

	 /** Initializes the GPSService */
    private void initializeService(){
    	
    	Intent intent = new Intent();
    	intent.setClassName("com.android.task5", "com.android.task5.GPSService");
    	serviceConnection = new GPSServiceConnection();
    	bindService(intent,serviceConnection,Context.BIND_AUTO_CREATE);
       
    }
	
	
    /** Creates the menu items */
    public boolean onCreateOptionsMenu(Menu menu) {
    	Log.i("btn","HERE");
    	appMenu = menu;
    	
    	appMenu.add(0, MENU_START, 0, "Start");
    	appMenu.add(0, MENU_CHANGE_MODE, 0, "GPS On");
    	appMenu.add(0, MENU_GET_PHOTOS, 0, "Get Photos");
		appMenu.getItem(MENU_CHANGE_MODE).setEnabled(false);
		appMenu.getItem(MENU_GET_PHOTOS).setEnabled(false);

        return true;
    }
    
    /** Handles item selections */
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case MENU_START:
        	toogleOnOff();
            return true;
        case MENU_CHANGE_MODE:
        	if(started)
        		changeMode();
        	return true;
        case MENU_GET_PHOTOS:
        	getPhotos();
        	return true;
        }
        return false;
    }
	
    /** Determines map clipping. Starts the ImageViewActivity and passes the map clipping data
     * to this activity. */
    private void getPhotos(){
    	
    	//Longitude for the center point
	 	int centerLongitude = mapView.getMapCenter().getLongitudeE6();
	 	// Latitude for the center point
    	int centerLatitude = mapView.getMapCenter().getLatitudeE6();
    	
    	// The latitude "distance" from north to south on the current map view.
    	int latitudeSpan = mapView.getLatitudeSpan();
    	// The longitude "distance" from north to south on the current map view.
    	int longitudeSpan = mapView.getLongitudeSpan();
    	
    	// To find the north boarder: Add the coordinates for the center latitude point and
    	// add half of the latitude span
    	int northBoarder = centerLatitude + (latitudeSpan/2);
    	// To find the south boarder: Add the coordinates for the center latitude point and
    	// subtract half of the latitude span
    	int southBoarder = centerLatitude - (latitudeSpan/2);
    	// To find the east boarder: Add the coordinates for the center longitude point and
    	// add half of the longitude span
    	int eastBoarder = centerLongitude + (longitudeSpan/2);
    	// To find the west boarder: Add the coordinates for the center longitude point and
    	// subtract half of the longitude span
    	int westBoarder = centerLongitude - (longitudeSpan/2);
    	
    	Intent intent = new Intent(this,ImageViewActivity.class);
    	intent.putExtra("centerLongitude", centerLongitude);
    	intent.putExtra("centerLatitude", centerLatitude);
    	intent.putExtra("northBoarder", northBoarder);
    	intent.putExtra("southBoarder", southBoarder);
    	intent.putExtra("westBoarder", westBoarder);
    	intent.putExtra("eastBoarder", eastBoarder);
    	startActivity(intent);
    	
    }
    /** Turns on/off the GPS */
    private void changeMode(){
    	
    	if(!started)
    		return;
    	
    	try {
			isGPSActivated = serviceProxy.toogleGPSOnOff();

			if(!isGPSActivated){
				appMenu.getItem(MENU_CHANGE_MODE).setTitle("GPS On");
				reDraw(null);
			}
			else
				appMenu.getItem(MENU_CHANGE_MODE).setTitle("GPS Off");

			
		} catch (RemoteException e) {
			e.printStackTrace();
		}
    }
	
	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}
	
	/** Callback method used by the GPSService to update latitude and longitude values  */
	private callBackService.Stub callBackService = new callBackService.Stub(){

		@Override
		public void updateLocation(double latNew, double longNew)
				throws RemoteException {
			
			latitude = latNew;
			longitude = longNew;
			
			Location loc = new Location("");
			loc.setLatitude(latitude);
			loc.setLongitude(longitude);
			
			updatePosition(loc);
		}
		
	};
	
	/** Updates the current position. Stores this position in a GeoPoint and redraws the circle
	 * according to the new position  */
	
	public void updatePosition(Location newLocation) {
		
		Log.i("Loc","Updated");
		

//		// transform the location to a geopoint
		GeoPoint geopoint = new GeoPoint(
				(int) (newLocation.getLatitude() * 1E6), (int) (newLocation
						.getLongitude() * 1E6));
		reDraw(geopoint);
	}
	
	/** Removes, if existing, old overlays. Creates a new overlay and adds this to the MapView  */
	
	private void reDraw(GeoPoint geoPoint){

		List<Overlay> overlays = mapView.getOverlays();
		// 
		// first remove old overlay
		if (overlays.size()!= 0) {
			for (Iterator<Overlay> iterator = overlays.iterator(); iterator.hasNext();) {
				iterator.next();
				iterator.remove();
			}
		}
		//Create a custom overlay
		overlay = new CustomOverlay(geoPoint);

		// Add the custom overlay to the mapView.
		mapView.getOverlays().add(overlay);
		// 
		//				// move to location
		if(geoPoint != null)
			mapView.getController().animateTo(geoPoint);

		//Redraw the map
		mapView.postInvalidate();
	}

	/** Starts/Stops the application.  */
    private void toogleOnOff(){
		if(!started){
			try {
				serviceProxy.setCallBack(callBackService.asBinder());
				appMenu.getItem(MENU_CHANGE_MODE).setEnabled(true);
				appMenu.getItem(MENU_GET_PHOTOS).setEnabled(true);
			} catch (RemoteException e) {
				e.printStackTrace();
			}
			started = true;
			appMenu.getItem(MENU_START).setTitle("Exit");
		}
		else{
			started = false;
			finish();
		}
    }
	
	
    class GPSServiceConnection implements ServiceConnection
    {
		public void onServiceConnected(ComponentName arg0, IBinder boundService) {
			serviceProxy = service.Stub.asInterface(boundService);
		}

		public void onServiceDisconnected(ComponentName arg0) {
			serviceProxy = null;
		}
    };
}